package controllers

import (
	"encoding/base64"
	"ginstudydemo.com/main/service"
	"github.com/dchest/captcha"
	"github.com/gin-gonic/gin"
	"os"
)

type CaptchaRes struct {
	CaptchaKey    string `json:"captchaKey"`
	CaptchaBase64 string `json:"captchaBase64"`
}

var CaptchaForm struct {
	// 验证码的 ID，即在生成验证码时返回的唯一标识符。（加密）
	CapId string `json:"capId" binding:"required"`
	// 用户输入的验证码字符串。
	InputCaptcha string `json:"inputCaptcha" binding:"required"`
}

type ICaptchaController interface {
	Generate()
	Verify()
}

type CaptchaController struct{}

func NewCaptchaController() *CaptchaController {
	return &CaptchaController{}
}

// Generate 生成新的验证码 ID 和 Base64 编码的验证码图片
func (ct CaptchaController) Generate(c *gin.Context) {
	capId := captcha.New()
	// 定义二维码图片存储目录
	captchaDir := "runtime/captcha/"
	captchaImagePath := captchaDir + "cap" + ".png"
	// 目录是否存在，不存在创建目录
	if osMkerr := os.MkdirAll(captchaDir, os.ModePerm); osMkerr != nil {
		service.ReturnErr(c, "5001", "无法创建验证码图片目录")
		return
	}
	// 创建文件用于保存验证码图片
	captchaFile, osErr := os.Create(captchaImagePath)
	if osErr != nil {
		service.ReturnErr(c, "5001", "无法创建验证码图片文件")
		return
	}
	defer captchaFile.Close()

	// 生成验证码图片并保存
	captcha.WriteImage(captchaFile, capId, 240, 80)
	imageBytes, err := os.ReadFile(captchaImagePath)
	if err != nil {
		service.ReturnErr(c, "5001", "无法读取验证码图片")
		c.Abort()
	}
	// 将图片转为 Base64
	base64Image := "data:image/png;base64," + base64.StdEncoding.EncodeToString(imageBytes)
	service.ReturnSuccess[CaptchaRes](c, "2000", "用户ok", CaptchaRes{
		CaptchaKey:    capId,
		CaptchaBase64: base64Image,
	})

}

// Verify 验证验证码
func (ct CaptchaController) Verify(c *gin.Context) {
	//获取表单数据 验证码id 和  输入的验证码
	if cErr := c.BindJSON(&CaptchaForm); cErr != nil {
		service.ReturnErr(c, "5001", cErr)
		c.Abort()
		return
	}
	valid := service.NewCaptchaService().Verify(CaptchaForm.CapId, CaptchaForm.InputCaptcha)
	//valid := captcha.VerifyString(CaptchaForm.CapId, CaptchaForm.InputCaptcha)
	if valid {
		service.ReturnSuccess[bool](c, "2000", "用户ok", true)
	} else {
		service.ReturnSuccess[bool](c, "2000", "用户ok", false)
	}
}
